import re
import allure
from enum import Enum
from typing import Union, Any, Literal
import json

from jsonpath import jsonpath
from hamcrest import *
from jsonschema import validate, ValidationError

from pyassured.core.global_data import global_data
from pyassured.core.logger import Log
from pyassured.core.emoji_utils import EmojiUtils
from pyassured.core.log_helper import LogHelper
from pyassured.core.database_assertions import assert_single_record, assert_multiple_records

log = Log()


class AssertionType(Enum):
    """断言类型枚举"""
    EQUALS = "equals"
    EQUAL_TO = "equal_to"
    CONTAINS = "contains"
    CONTAINS_STRING = "contains_string"
    NOT_NONE = "not_none"
    IS_NONE = "is_none"
    GREATER_THAN = "greater_than"
    LESS_THAN = "less_than"
    GREATER_THAN_OR_EQUAL_TO = "greater_than_or_equal_to"
    LESS_THAN_OR_EQUAL_TO = "less_than_or_equal_to"
    MATCHES_REGEX = "matches_regex"
    HAS_LENGTH = "has_length"
    IS_IN = "is_in"
    STARTS_WITH = "starts_with"
    ENDS_WITH = "ends_with"
    # 新增的PyHamcrest匹配器
    ANYTHING = "anything"
    ALL_OF = "all_of"
    ANY_OF = "any_of"
    HAS_ENTRIES = "has_entries"
    HAS_ENTRY = "has_entry"
    HAS_KEY = "has_key"
    HAS_VALUE = "has_value"
    HAS_PROPERTY = "has_property"
    HAS_PROPERTIES = "has_properties"
    INSTANCE_OF = "instance_of"
    SAME_INSTANCE = "same_instance"
    CLOSE_TO = "close_to"
    STRING_CONTAINS_IN_ORDER = "string_contains_in_order"
    MATCHES_REGEXP = "matches_regexp"
    HAS_STRING = "has_string"


class BaseAssertion:

    def __init__(self, response):
        self.__response = response
        self.__actual_value = None

    def should(self, assertion_type: Union[Literal[
        "equals", "equal_to", "contains", "contains_string", "not_none", "is_none", "greater_than", "less_than", "greater_than_or_equal_to", "less_than_or_equal_to", "matches_regex", "has_length", "is_in", "starts_with", "ends_with", "anything", "all_of", "any_of", "has_entries", "has_entry", "has_key", "has_value", "has_property", "has_properties", "instance_of", "same_instance", "close_to", "string_contains_in_order", "matches_regexp", "has_string"], AssertionType],
               expected_value: Any = None):
        """执行断言
        
        Args:
            assertion_type (Union[str, AssertionType]): 断言类型，支持字符串或AssertionType枚举
            expected_value: 期望值（某些断言类型不需要）
            
        Returns:
            ValidatableResponse: 返回原始的ValidatableResponse对象以支持链式调用
        """
        # 如果传入的是枚举类型，获取其值
        if isinstance(assertion_type, AssertionType):
            assertion_type = assertion_type.value
        assertion_map = {
            # 基础断言
            'equals': equal_to,
            'equal_to': equal_to,
            'contains': contains_string,
            'contains_string': contains_string,
            'not_none': is_not(none()),
            'is_none': none(),

            # 数值比较
            'greater_than': greater_than,
            'less_than': less_than,
            'greater_than_or_equal_to': greater_than_or_equal_to,
            'less_than_or_equal_to': less_than_or_equal_to,
            'close_to': close_to,

            # 字符串匹配
            'matches_regex': lambda pattern: matches_regexp(pattern) if self._is_valid_regex(pattern) else None,
            'matches_regexp': lambda pattern: matches_regexp(pattern) if self._is_valid_regex(pattern) else None,
            'starts_with': starts_with,
            'ends_with': ends_with,
            'string_contains_in_order': string_contains_in_order,
            'has_string': has_string,

            # 集合和序列
            'has_length': has_length,
            'is_in': is_in,
            'contains': contains,

            # 字典和对象
            'has_entries': has_entries,
            'has_entry': has_entry,
            'has_key': has_key,
            'has_value': has_value,
            'has_property': has_property,
            'has_properties': has_properties,

            # 类型和实例
            'instance_of': instance_of,
            'same_instance': same_instance,

            # 逻辑组合
            'anything': anything(),
            'all_of': all_of,
            'any_of': any_of
        }

        func = assertion_map.get(assertion_type)
        if not func:
            raise ValueError(f"不支持的断言类型: {assertion_type}")

        step_name = self._get_step_name_with_assertion(assertion_type, expected_value)
        with allure.step(step_name):
            try:
                if assertion_type in ['not_none', 'is_none', 'anything']:
                    assert_that(self.__actual_value, func)
                elif assertion_type == 'matches_regex':
                    if not self._is_valid_regex(expected_value):
                        raise ValueError(f"无效的正则表达式: {expected_value}")
                    if not re.search(expected_value, str(self.__actual_value)):
                        raise AssertionError(f"值 '{self.__actual_value}' 不匹配正则表达式 '{expected_value}'")
                else:
                    if expected_value is None and assertion_type not in ['not_none', 'is_none', 'anything']:
                        raise ValueError(f"断言类型 '{assertion_type}' 需要提供 expected_value")
                    assert_that(self.__actual_value, func(expected_value))

                self._print_step(expected_value, self.__actual_value, True)
            except AssertionError as e:
                self._print_step(expected_value, self.__actual_value, False)
                raise

        return self._get_parent_response()

    def _get_parent_response(self):
        """获取父级ValidatableResponse对象"""
        return ValidatableResponse(self.__response)

    def _print_step(self, expected_value, actual_value, passed=True):
        pass

    def _get_step_name(self):
        return "执行断言"

    def _get_step_name_with_assertion(self, assertion_type, expected_value):
        """获取包含断言方法信息的步骤名称"""
        base_name = self._get_step_name()
        assertion_info = f" should({assertion_type}"
        if expected_value is not None and assertion_type not in ['not_none', 'is_none']:
            assertion_info += f", {expected_value}"
        assertion_info += ")"
        return base_name + assertion_info

    def _is_valid_regex(self, regex):
        """验证正则表达式是否有效"""
        if regex is None:
            return False
        try:
            re.compile(regex)
            return True
        except TypeError:
            return False

    def extract(self):
        """提取当前断言对象的实际值
        
        Returns:
            Any: 提取的实际值
        """
        log.info(f"{EmojiUtils.DATA_EXTRACT} 提取断言值: {self.__actual_value}")
        return self.__actual_value


class JsonPathAssertion(BaseAssertion):
    """JSON路径断言类，支持链式调用"""

    def __init__(self, response, json_path, position=0):
        super().__init__(response)
        self.__json_path = json_path
        self.__position = position
        self.__extract_value()

    def __extract_value(self):
        """提取JSON路径对应的值"""
        try:
            actual_value = jsonpath(self._BaseAssertion__response.json(), self.__json_path)
            if type(actual_value) is not list:
                error_msg = f"JSON路径不存在或格式错误: {self.__json_path}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)
            self._BaseAssertion__actual_value = actual_value[self.__position]
        except (TypeError, IndexError) as e:
            error_msg = f"JSON路径不存在或索引错误: {self.__json_path}, 位置: {self.__position}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)

    def _get_step_name(self):
        return f"检查JSON路径 {EmojiUtils.JSON_PATH} [{self.__json_path}]"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion_with_path("json_path", expected_value, actual_value, passed, self.__json_path)


class StatusCodeAssertion(BaseAssertion):
    """状态码断言类，支持链式调用"""

    def __init__(self, response):
        super().__init__(response)
        self._BaseAssertion__actual_value = self._BaseAssertion__response.status_code

    def _get_step_name(self):
        return f"检查状态码 {EmojiUtils.ASSERT_STATUS}"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion("status_code", expected_value, actual_value, passed)


class BodyAssertion(BaseAssertion):
    """响应体断言类，支持链式调用"""

    def __init__(self, response):
        super().__init__(response)
        self._BaseAssertion__actual_value = self._BaseAssertion__response.text

    def _get_step_name(self):
        return f"检查响应体 {EmojiUtils.BODY}"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion("body", expected_value, actual_value, passed)


class HeaderAssertion(BaseAssertion):
    """响应头断言类，支持链式调用"""

    def __init__(self, response, key):
        super().__init__(response)
        self.__key = key
        try:
            self._BaseAssertion__actual_value = self._BaseAssertion__response.headers[key]
        except KeyError:
            error_msg = f"响应头中不存在键: {key}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise KeyError(error_msg)

    def _get_step_name(self):
        return f"检查响应头 {EmojiUtils.HEADER} [{self.__key}]"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion("header", expected_value, actual_value, passed)


class CookieAssertion(BaseAssertion):
    """Cookie断言类，支持链式调用"""

    def __init__(self, response, key):
        super().__init__(response)
        self.__key = key
        try:
            self._BaseAssertion__actual_value = self._BaseAssertion__response.cookies.get(key)
            if self._BaseAssertion__actual_value is None:
                error_msg = f"Cookie中不存在键: {key}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise KeyError(error_msg)
        except Exception as e:
            error_msg = f"Cookie中不存在键: {key}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise KeyError(error_msg)

    def _get_step_name(self):
        return f"检查Cookie {EmojiUtils.COOKIE} [{self.__key}]"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion("cookie", expected_value, actual_value, passed)


class BodyRegularAssertion(BaseAssertion):
    """响应体正则断言类，支持链式调用"""

    def __init__(self, response, regex, position=1):
        super().__init__(response)
        self.__regex = regex
        self.__position = position
        self.__extract_value()

    def __extract_value(self):
        """使用正则表达式提取响应体中的值"""
        response_message = self._BaseAssertion__response.text
        try:
            match = re.search(self.__regex, response_message)
            if match:
                self._BaseAssertion__actual_value = match.group(self.__position)
            else:
                raise AttributeError(f"正则表达式未匹配到内容: {self.__regex}")
        except (AttributeError, IndexError) as e:
            error_msg = f"正则表达式匹配失败: {self.__regex}, 位置: {self.__position}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)

    def _get_step_name(self):
        return f"检查响应体正则匹配 {EmojiUtils.ASSERT_REGEX} [{self.__regex}]"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion_with_path("body_regex", expected_value, actual_value, passed, self.__regex)


class JsonSchemaAssertion(BaseAssertion):
    """JSON Schema断言类，支持链式调用"""

    def __init__(self, response, schema):
        super().__init__(response)
        self.__schema = schema
        self.__json_data = None
        self.__extract_json_data()

    def __extract_json_data(self):
        """提取响应中的JSON数据"""
        try:
            self.__json_data = self._BaseAssertion__response.json()
            self._BaseAssertion__actual_value = self.__json_data
        except (ValueError, json.JSONDecodeError) as e:
            error_msg = f"响应体不是有效的JSON格式: {str(e)}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)

    def should_match_schema(self):
        """验证JSON数据是否符合指定的Schema
        
        Returns:
            ValidatableResponse: 返回原始的ValidatableResponse对象以支持链式调用
        """
        step_name = f"验证JSON Schema {EmojiUtils.JSON_PATH}"
        with allure.step(step_name):
            try:
                validate(instance=self.__json_data, schema=self.__schema)
                self._print_step("符合Schema", "验证通过", True)
                log.info(f"{EmojiUtils.SUCCESS} JSON数据符合指定的Schema")
            except ValidationError as e:
                error_msg = f"JSON数据不符合Schema: {e.message}"
                self._print_step("符合Schema", f"验证失败: {e.message}", False)
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise AssertionError(error_msg)
            except Exception as e:
                error_msg = f"Schema验证过程中发生错误: {str(e)}"
                self._print_step("符合Schema", f"验证错误: {str(e)}", False)
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)

        return self._get_parent_response()

    def should_not_match_schema(self):
        """验证JSON数据不符合指定的Schema
        
        Returns:
            ValidatableResponse: 返回原始的ValidatableResponse对象以支持链式调用
        """
        step_name = f"验证JSON不符合Schema {EmojiUtils.JSON_PATH}"
        with allure.step(step_name):
            try:
                validate(instance=self.__json_data, schema=self.__schema)
                error_msg = "JSON数据意外地符合了Schema，但期望不符合"
                self._print_step("不符合Schema", "验证失败: 数据符合Schema", False)
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise AssertionError(error_msg)
            except ValidationError:
                self._print_step("不符合Schema", "验证通过", True)
                log.info(f"{EmojiUtils.SUCCESS} JSON数据按预期不符合指定的Schema")
            except Exception as e:
                error_msg = f"Schema验证过程中发生错误: {str(e)}"
                self._print_step("不符合Schema", f"验证错误: {str(e)}", False)
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)

        return self._get_parent_response()

    def get_validation_errors(self):
        """获取详细的验证错误信息
        
        Returns:
            list: 验证错误列表
        """
        errors = []
        try:
            validate(instance=self.__json_data, schema=self.__schema)
        except ValidationError as e:
            errors.append({
                'message': e.message,
                'path': list(e.absolute_path),
                'schema_path': list(e.schema_path),
                'validator': e.validator,
                'validator_value': e.validator_value
            })
        except Exception as e:
            errors.append({
                'message': f"Schema验证过程中发生错误: {str(e)}",
                'path': [],
                'schema_path': [],
                'validator': 'unknown',
                'validator_value': None
            })

        log.info(f"{EmojiUtils.DATA_EXTRACT} 提取验证错误信息: {len(errors)} 个错误")
        return errors

    def _get_step_name(self):
        return f"检查JSON Schema {EmojiUtils.JSON_PATH}"

    def _print_step(self, expected_value, actual_value, passed=True):
        LogHelper.log_assertion("json_schema", expected_value, actual_value, passed)


class ValidatableResponse():

    def __init__(self, response):
        self.__response = response

    def body(self):
        """获取响应体断言对象
        
        Returns:
            BodyAssertion: 响应体断言对象，支持链式调用
        """
        return BodyAssertion(self.__response)

    def body_regular(self, regex, position=1):
        """获取响应体正则断言对象
        
        Args:
            regex (str): 正则表达式
            position (int): 匹配组位置，默认为1
            
        Returns:
            BodyRegularAssertion: 响应体正则断言对象，支持链式调用
        """
        return BodyRegularAssertion(self.__response, regex, position)

    def status_code(self):
        """获取状态码断言对象
        
        Returns:
            StatusCodeAssertion: 状态码断言对象，支持链式调用
        """
        return StatusCodeAssertion(self.__response)

    def header(self, key):
        """获取响应头断言对象
        
        Args:
            key (str): 响应头键名
            
        Returns:
            HeaderAssertion: 响应头断言对象，支持链式调用
        """
        return HeaderAssertion(self.__response, key)

    def headers(self, actual_headers, expected_headers):
        """验证多个响应头"""
        try:
            with allure.step(f"检查多个响应头 {EmojiUtils.HEADER}"):
                try:
                    assert_that(actual_headers, has_entries(expected_headers))
                    self.__print_step(expected_headers, actual_headers, "headers", True)
                except AssertionError as e:
                    self.__print_step(expected_headers, actual_headers, "headers", False)
                    raise
        except KeyError:
            error_msg = f"断言响应头失败，实际响应头: {actual_headers}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise KeyError(error_msg)
        return self

    def cookie(self, key):
        """获取Cookie断言对象
        
        Args:
            key (str): Cookie键名
            
        Returns:
            CookieAssertion: Cookie断言对象，支持链式调用
        """
        return CookieAssertion(self.__response, key)

    def cookies(self, actual_cookies, expected_cookies):
        """验证多个Cookie"""
        try:
            with allure.step(f"检查多个Cookie {EmojiUtils.COOKIE}"):
                try:
                    assert_that(actual_cookies, has_entries(expected_cookies))
                    self.__print_step(expected_cookies, actual_cookies, "cookies", True)
                except AssertionError as e:
                    self.__print_step(expected_cookies, actual_cookies, "cookies", False)
                    raise
        except KeyError:
            error_msg = f"断言Cookie失败，实际Cookie: {actual_cookies}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise KeyError(error_msg)
        return self

    def json_path(self, json_path, position=0):
        """验证JSON路径的值
        
        Args:
            json_path (str): JSON路径表达式
            position (int): 数组位置，默认为0
            
        Returns:
            JsonPathAssertion: 返回JsonPathAssertion对象支持链式调用
        """
        return JsonPathAssertion(self.__response, json_path, position)

    def json_schema(self, schema):
        """验证JSON响应是否符合指定的Schema
        
        Args:
            schema (dict): JSON Schema定义
            
        Returns:
            JsonSchemaAssertion: 返回JsonSchemaAssertion对象支持链式调用
            
        Example:
            # 定义Schema
            user_schema = {
                "type": "object",
                "properties": {
                    "id": {"type": "integer"},
                    "name": {"type": "string"},
                    "email": {"type": "string", "format": "email"}
                },
                "required": ["id", "name", "email"]
            }
            
            # 使用Schema验证
            response.json_schema(user_schema).should_match_schema()
        """
        return JsonSchemaAssertion(self.__response, schema)

    def extract(self):
        """获取响应提取器
        
        Returns:
            ExtractableResponse: 用于提取数据的响应对象
        """
        log.info(f"{EmojiUtils.DATA_EXTRACT} 切换到数据提取模式")
        return ExtractableResponse(self.__response)

    def response(self):
        """获取原始响应对象
        
        Returns:
            requests.Response: HTTP响应对象
        """
        log.info(f"{EmojiUtils.RESPONSE} 获取原始响应对象")
        return self

    def database(self):
        """获取数据库断言器
        
        Returns:
            DatabaseAssertionHelper: 数据库断言辅助类
        """
        log.info(f"{EmojiUtils.DATABASE} 切换到数据库断言模式")
        return DatabaseAssertionHelper()

    def database_single(self, sql: str, params: tuple = None, env: str = None):
        """创建单条记录数据库断言
        
        Args:
            sql: SQL查询语句
            params: 查询参数
            env: 指定环境，如果不指定则使用配置文件中的默认环境
            
        Returns:
            SingleRecordAssertion: 单条记录断言对象
        """
        log.info(f"{EmojiUtils.DATABASE} 创建单条记录数据库断言")
        return assert_single_record(sql, params, env)

    def database_multiple(self, sql: str, params: tuple = None, env: str = None):
        """创建多条记录数据库断言
        
        Args:
            sql: SQL查询语句
            params: 查询参数
            env: 指定环境，如果不指定则使用配置文件中的默认环境
            
        Returns:
            MultipleRecordsAssertion: 多条记录断言对象
        """
        log.info(f"{EmojiUtils.DATABASE} 创建多条记录数据库断言")
        return assert_multiple_records(sql, params, env)

    def __print_step(self, expected_value, actual_value, assert_type=None, passed=True):
        """打印断言步骤"""
        # 使用LogHelper记录断言日志
        LogHelper.log_assertion(assert_type, expected_value, actual_value, passed)


class DatabaseAssertionHelper:
    """数据库断言辅助类"""

    def single_record(self, sql: str, params: tuple = None, env: str = None):
        """创建单条记录断言
        
        Args:
            sql: SQL查询语句
            params: 查询参数
            env: 指定环境，如果不指定则使用配置文件中的默认环境
            
        Returns:
            SingleRecordAssertion: 单条记录断言对象
        """
        return assert_single_record(sql, params, env)

    def multiple_records(self, sql: str, params: tuple = None, env: str = None):
        """创建多条记录断言
        
        Args:
            sql: SQL查询语句
            params: 查询参数
            env: 指定环境，如果不指定则使用配置文件中的默认环境
            
        Returns:
            MultipleRecordsAssertion: 多条记录断言对象
        """
        return assert_multiple_records(sql, params, env)


class ExtractableResponse():

    def __init__(self, response):
        """初始化可提取响应对象
        
        Args:
            response: HTTP响应对象
        """
        if response is None:
            raise ValueError("响应对象不能为空")
        self.__response = response
        self.__step_var = {}
        log.info(f"{EmojiUtils.DATA_EXTRACT} 创建数据提取器")

    def _store_and_log_extraction(self, extract_type, extract_var, extract_value, is_global=False, key=None):
        """统一处理变量存储和日志记录
        
        Args:
            extract_type: 提取类型
            extract_var: 变量名
            extract_value: 提取的值
            is_global: 是否为全局变量
            key: 额外的键信息（如header key, cookie key等）
        """
        if extract_var is None:
            log.warning(f"{EmojiUtils.WARNING} 未指定变量名，跳过存储")
            return

        self.__step_var[extract_var] = extract_value

        if is_global:
            global_data.set_data(extract_var, extract_value)
            scope = "全局变量"
        else:
            scope = "局部变量"

        # 使用LogHelper记录提取日志
        LogHelper.log_extraction(extract_type, extract_var, extract_value, scope, key)

    def _validate_extract_var(self, extract_var):
        """验证变量名的有效性
        
        Args:
            extract_var: 变量名
            
        Raises:
            ValueError: 当变量名无效时
        """
        if extract_var is not None and not isinstance(extract_var, str):
            raise ValueError(f"变量名必须是字符串类型，当前类型: {type(extract_var)}")
        if extract_var is not None and not extract_var.strip():
            raise ValueError("变量名不能为空字符串")

    def status_code(self, extract_var=None, is_global=False):
        """提取状态码
        
        Args:
            extract_var: 变量名
            is_global: 是否存储为全局变量
            
        Returns:
            ExtractableResponse: 支持链式调用
        """
        self._validate_extract_var(extract_var)
        extract_value = self.__response.status_code
        self._store_and_log_extraction("status_code", extract_var, extract_value, is_global)
        return self

    def header(self, key, extract_var=None, is_global=False):
        """提取响应头
        
        Args:
            key: 响应头键名
            extract_var: 变量名
            is_global: 是否存储为全局变量
            
        Returns:
            ExtractableResponse: 支持链式调用
            
        Raises:
            ValueError: 当key为空时
            KeyError: 当响应头中不存在指定键时
        """
        if not key or not isinstance(key, str):
            raise ValueError("响应头键名不能为空且必须是字符串")
        self._validate_extract_var(extract_var)

        try:
            extract_value = self.__response.headers[key]
            self._store_and_log_extraction("header", extract_var, extract_value, is_global, key)
        except KeyError:
            error_msg = f"响应头中不存在键: {key}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise KeyError(error_msg)

        return self

    def cookie(self, key, extract_var=None, is_global=False):
        """提取Cookie
        
        Args:
            key: Cookie键名
            extract_var: 变量名
            is_global: 是否存储为全局变量
            
        Returns:
            ExtractableResponse: 支持链式调用
            
        Raises:
            ValueError: 当key为空时
            KeyError: 当Cookie中不存在指定键时
        """
        if not key or not isinstance(key, str):
            raise ValueError("Cookie键名不能为空且必须是字符串")
        self._validate_extract_var(extract_var)

        try:
            extract_value = self.__response.cookies.get(key)
            if extract_value is None:
                error_msg = f"Cookie中不存在键: {key}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise KeyError(error_msg)

            self._store_and_log_extraction("cookie", extract_var, extract_value, is_global, key)
        except KeyError:
            raise
        except Exception as e:
            error_msg = f"提取Cookie失败: {key}, 错误: {str(e)}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)

        return self

    def body(self, regex, extract_var=None, position=1, is_global=False):
        """使用正则表达式从响应体提取数据
        
        Args:
            regex: 正则表达式
            extract_var: 变量名
            position: 捕获组位置（从1开始）
            is_global: 是否存储为全局变量
            
        Returns:
            ExtractableResponse: 支持链式调用
            
        Raises:
            ValueError: 当正则表达式无效或匹配失败时
        """
        if not regex or not isinstance(regex, str):
            raise ValueError("正则表达式不能为空且必须是字符串")
        if not isinstance(position, int) or position < 1:
            raise ValueError("捕获组位置必须是大于0的整数")
        self._validate_extract_var(extract_var)

        try:
            # 验证正则表达式的有效性
            re.compile(regex)

            response_message = self.__response.text
            match_result = re.search(regex, response_message)

            if not match_result:
                error_msg = f"正则表达式匹配失败: {regex}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)

            if position > match_result.lastindex or match_result.lastindex is None:
                error_msg = f"捕获组位置超出范围: {position}, 最大位置: {match_result.lastindex or 0}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)

            extract_value = match_result.group(position)
            self._store_and_log_extraction("body_regex", extract_var, extract_value, is_global, regex)
        except re.error as e:
            error_msg = f"正则表达式语法错误: {regex}, 错误: {str(e)}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)
        except (AttributeError, IndexError) as e:
            error_msg = f"正则表达式提取失败: {regex}, 位置: {position}, 错误: {str(e)}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)

        return self

    def json_path(self, json_path, extract_var=None, position=0, is_global=False):
        """从JSON响应中提取数据
        
        Args:
            json_path: JSON路径表达式
            extract_var: 变量名
            position: 结果数组中的位置（从0开始）
            is_global: 是否存储为全局变量
            
        Returns:
            ExtractableResponse: 支持链式调用
            
        Raises:
            ValueError: 当JSON路径无效或提取失败时
        """
        if not json_path or not isinstance(json_path, str):
            raise ValueError("JSON路径不能为空且必须是字符串")
        if not isinstance(position, int) or position < 0:
            raise ValueError("位置索引必须是非负整数")
        self._validate_extract_var(extract_var)

        try:
            # 先验证响应是否为有效JSON
            json_data = self.__response.json()
            json_result = jsonpath(json_data, json_path)

            if not json_result or not isinstance(json_result, list):
                error_msg = f"JSON路径未匹配到任何结果: {json_path}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)

            if len(json_result) <= position:
                error_msg = f"JSON路径结果索引越界: {json_path}, 位置: {position}, 实际长度: {len(json_result)}"
                log.error(f"{EmojiUtils.ERROR} {error_msg}")
                raise ValueError(error_msg)

            extract_value = json_result[position]
            self._store_and_log_extraction("json_path", extract_var, extract_value, is_global, json_path)
        except ValueError:
            raise
        except Exception as e:
            error_msg = f"JSON路径提取失败: {json_path}, 位置: {position}, 错误: {str(e)}"
            log.error(f"{EmojiUtils.ERROR} {error_msg}")
            raise ValueError(error_msg)

        return self

    def response(self):
        """获取原始响应对象
        
        Returns:
            requests.Response: HTTP响应对象
        """
        log.info(f"{EmojiUtils.RESPONSE} 获取原始响应对象")
        return self.__response

    def step_values(self):
        """获取当前步骤中提取的所有变量
        
        Returns:
            Dict: 提取的变量字典
        """
        if self.__step_var:
            log.info(f"{EmojiUtils.DATA_EXTRACT} 返回提取的变量: {list(self.__step_var.keys())}")
        return self.__step_var
